//
// Created by gastonfeng on 2023/8/8.
//
#ifdef USE_DHT11
#include <Arduino.h>
#include "dht.h"
#include "rtos.h"

uint32_t last_us;
uint16_t log_data[45];
uint32_t data_index;
u8 bit_data[5];
void pin_cb()
{
    uint32_t us = dwt_getCycles();
    uint32_t diff = us - last_us;
    last_us = us;
    if (data_index < 45) {
        log_data[data_index++] = diff;
    }
}

int dht::begin(u8 _pin)
{
    pin = _pin;
    return 0;
}

int dht::read11()
{
    if (Rtos::ticks() - last_tick > 1500)
    {
        last_tick = Rtos::ticks();
        memset(bit_data, 0, sizeof(bit_data));
        pinMode(pin, OUTPUT);
        digitalWrite(pin, LOW);
        Rtos::Delay(30);
        pinMode(pin, INPUT_PULLUP);
        attachInterrupt(pin, pin_cb, FALLING);
        data_index = 0;
    }
    int comp = SystemCoreClock / 10000;
    if (data_index > 40)
    {
        for (int i = 0; i < 40; i++)
        {
            if (log_data[i + 1] > comp) {
                bit_data[i / 8] |= 1 << (7 - (i % 8));
            }
        }
        data_index = 0;
        u8 sum = bit_data[0] + bit_data[1] + bit_data[2] + bit_data[3];
        if (sum == bit_data[4] && (bit_data[0] < 100) && (bit_data[2] < 100))
        {
            humidity = bit_data[0] + bit_data[1] / 10.0;
            temperature = bit_data[2] + bit_data[3] / 10.0;
            return 0;
        }
    }
    return 0;
}

int dht::read2303() {
    if (Rtos::ticks() - last_tick > 1500) {
        last_tick = Rtos::ticks();
        memset(bit_data, 0, sizeof(bit_data));
        pinMode(pin, OUTPUT);
        digitalWrite(pin, LOW);
        Rtos::Delay(30);
        pinMode(pin, INPUT_PULLUP);
        attachInterrupt(pin, pin_cb, FALLING);
        data_index = 0;
    }
    int comp = SystemCoreClock / 10000;
    if (data_index > 40) {
        for (int i = 0; i < 40; i++) {
            if (log_data[i + 1] > comp) {
                bit_data[i / 8] |= 1 << (7 - (i % 8));
            }
        }
        data_index = 0;
        u8 sum = bit_data[0] + bit_data[1] + bit_data[2] + bit_data[3];
        if (sum == bit_data[4]) {
            humidity = ((float) bit_data[0] * 256 + bit_data[1]) / 10.0;
            temperature = ((float) bit_data[2] * 256 + bit_data[3]) / 10.0;
            return 0;
        }
    }
    return 0;
}
#endif
